package com.CircleArrayQueue;

/**
2.0：通过取模变为环形队列
rear = front = 0 ， front表示队首元素的位置，而rear表示队尾元素后一个位置（也就是说maxSize=4，实际可以空间为3，需要预留一个空间
判空条件：rear = front
判满条件：(rear + 1) % maxSize = front
队列中的有效数字的个数：(rear + maxSize -front) % maxSize
 **/
public class CircleArrayQueue {
    private int maxSize;
    private int front;
    private int rear;
    private int[] arr; //用于存放数据，数组模拟队列

    //创建队列,进行初始化工作
    public CircleArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        arr = new int[maxSize];
        //当队列为空时，首尾指针都为0
        front = 0; //front指向队列头部
        rear = 0; //rear指向队列尾的后一个位置，预留一个空间
    }

    //判断队列是否满
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return rear == front;
    }

    //添加数据到队列
    public void addQueue(int n) {
        //添加数据到队列时，首先判断队列是否满
        if (isFull()) {
            System.out.println("队列已满，不能加入数据");
            return;
        }
        arr[rear] = n;
        //rear后移，取模后变为环形
        rear = (rear + 1) % maxSize;
    }

    //获取队列中的数据,出队列
    public int getQueue() {
        //判断队列是否尾空
        if (isEmpty()) {
            //通过抛出异常处理
            throw new RuntimeException("队列为空，没有数据获取");
        }
        int n = arr[front];
        front = (front + 1)%maxSize;
        return n;
    }

    //获取队列中的所有数据
    public void showQueue() {
        //判断对内是否为空
        if (isEmpty()) {
            System.out.println("队列为空，没有数据获取");
        }
        //获取数据时，队列内部的首位指针无需移动
        for (int i = front ; i < front + getLength(); i++) {
            System.out.print("arr["+i%maxSize+"] = "+arr[i%maxSize] + " ");
        }
        System.out.println();
    }

    //求出当前队列中有效数据的个数
    public int getLength(){
        return (rear + maxSize - front) % maxSize;
    }
    //显示队列的头部数据，不是取数据
    public int getHandData() {
        //判断队列是否尾空
        if (isEmpty()) {
            //通过抛出异常处理
            throw new RuntimeException("队列为空，没有数据获取");
        }
        //如果是++front，则改变了front的值，变成了删除队列
        return arr[front];
    }

    //查看队首和队尾指针
    public void showRearAndFront() {
        System.out.println("rear = " + rear + ", front = " + front);
    }
}
